package java学习.第18章_JDK8_17新特性;

import java.util.Comparator;
/**
 * Lambda表达式的使用
 * Lambda是一个匿名函数，我们可以把Lambda表达式理解为是一段可以
 * 传递的代码(将代码像数据一样进行传递) 。使用它可以写出更简洁、更
 * 灵活的代码。作为一种更紧凑的代码风格，使Java的语言表达能力得到了
 * 提升。
 * 1.举例： (o1,o2) -> Integer.compare(o1,o2);
 * 2.格式：
 *      -> :lambda操作符 或 箭头操作符
 *      ->左边：lambda形参列表 （其实就是接口中的抽象方法的形参列表）
 *      ->右边：lambda体 （其实就是重写的抽象方法的方法体）
 * 3. Lambda表达式的使用：（分为6种情况介绍）
 *    总结：
 *    ->左边：lambda形参列表的参数类型可以省略(类型推断)；
 *          如果lambda形参列表只有一个参数，其一对()也可以省略
 *    ->右边：lambda体应该使用一对{}包裹；
 *          如果lambda体只有一条执行语句（可能是return语句），省略这一对{}和return关键字
 * 4.Lambda表达式的本质：作为函数式接口的实例
 * 5. 如果一个接口中，只声明了一个抽象方法，则此接口就称为 函数式接口。
 *      我们可以在一个接口上使用 @FunctionalInterface 注解，
 *   这样做可以检查它是否是一个函数式接口。
 * 6. 所以以前用匿 名实现类表示的现在都可以用Lambda表达式来写。
 *
 * 函数式接口 所在的包
 *      JDK8 中声明的函数式接口都在 java.util.function 包下
 *
 */
public class C1_Lambda表达式 {
    public static void main(String[] args) {
        //只能有一个函数式函数   Lambda 表达式
        FooS foo=new FooS() {
            @Override
            public int add(int x, int y) {
                return 0;
            }
        };
        foo.add(1,2);

        FooS foos=(int x,int y) -> {System.out.println("hello");return x+y;};
        foos.add(3,4);

        //正常写法
        Comparator<Integer> comparator = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return Integer.compare(o1,o2);
            }
        };
        //Lambda表达式
        Comparator<Integer> comparator1 = ((o1, o2) -> {return Integer.compare(o1,o2);});
        Comparator<Integer> comparator2 = (o1, o2) -> Integer.compare(o1,o2);//同上

        //方法引用
        Comparator<Integer> comparator3 = Integer::compare;

        Comparator<Integer> comparator4 = Comparator.comparingInt(o -> o);//同上

    }
    /**
     * @FunctionalInterface
     * 1、该注解只能标记在"有且仅有一个抽象方法"的接口上。
     * 2、JDK8接口中的静态方法和默认方法，都不算是抽象方法。
     * 3、接口默认继承java.lang.Object，所以如果接口显示声明覆盖了Object中方法，那么也不算抽象方法。
     * 4、该注解不是必须的，如果一个接口符合"函数式接口"定义，那么加不加该注解都没有影响。
     *   加上该注解能够更好地让编译器进行检查。
     *   如果编写的不是函数式接口，但是加上了@FunctionInterface，那么编译器会报错。
     */
    @FunctionalInterface
    interface  FooS {
        public int add(int x,int y);//函数式接口可用

        public default int mul(int x,int y)
        {
            return x+y;
        }

        public static int div(int x,int y)
        {
            return x/y;
        }

    }

}


